package csnet.openflow;

import csnet.openflow.component.controller.Controller;
import csnet.openflow.component.link.ConstantLatencyLink;
import csnet.openflow.component.link.Link;
import csnet.openflow.component.packetGenerator.PcapGenerator;
import csnet.openflow.component.receiver.Receiver;
import csnet.openflow.component.switchx.Switch;
import csnet.openflow.config.Configuration;
import csnet.openflow.util.log.LoggerGenerator;

public class Simulator {
    private LoggerGenerator loggerGenerator;
    private PcapGenerator generator;
    private Switch switch1;
    private Controller controller;
    private Receiver receiver;
    private long interval;

    public Simulator(Configuration config) {
        interval = config.getInterval();
        loggerGenerator = config.getLogger();

        generator = config.getGenerator();
        generator.setLogger(loggerGenerator);

        switch1 = config.getSwitch();
        switch1.setLogger(loggerGenerator);

        controller = config.getController();
        controller.setLogger(loggerGenerator);

        receiver = new Receiver();
        receiver.setLogger(loggerGenerator);

        Link g2s = new ConstantLatencyLink(0);
        Link s2r = new ConstantLatencyLink(0);

        generator.connect(g2s);
        switch1.connect(g2s, s2r, controller, controller);
        receiver.connect(s2r);
    }

    public void run() {
        long time = generator.getStartTime() + interval;
        while (true) {
            boolean flag = generator.schedule(time);
            switch1.schedule(time);
            flag |= receiver.schedule(time);
            time += interval;
            if (!flag)
                break;
        }
        loggerGenerator.closeAll();
    }

    public static void main(String[] args) {
        String basePath = "./";
        if (args.length > 0) {
            basePath = args[0];
        }
        Configuration config = new Configuration(basePath + "config.ini");
        Simulator simulator = new Simulator(config);
        simulator.run();
    }
}
